package it.polimi.swKnights.SWIMv2.servlets.registration;

import it.polimi.swKnights.SWIMv2.ejb.captchaGenerator.CaptchaGeneratorRemote;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.AlreadyExistingException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.InvalidDateException;
import it.polimi.swKnights.SWIMv2.ejb.registration.UserCreationHandlerRemote;
import it.polimi.swKnights.SWIMv2.general.Errors;
import it.polimi.swKnights.SWIMv2.general.WebsiteParameters;
import it.polimi.swKnights.SWIMv2.servlets.SwimServlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RegistrationProcessData
 * 
 * The user eneter its data, sys check the validity and if user is available:
 * -add a entry in the ToConfirmUser -send him a confirmation mail Otherwise
 * messages are prompt
 * 
 */
public class RegistrationProcessData extends SwimServlet
{
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException
	{
		String destination = "./registration";

		Map<String, String> parameters = this.createCorrectMap(request
				.getParameterMap());
		if (this.missMandatory(parameters))
		{
			response.sendRedirect(response.encodeRedirectURL(destination
					+ this.createUrlParameters(parameters, "tooshort")));
			return;
		}

		if (this.noSamePassword(parameters))
		{
			response.sendRedirect(response.encodeRedirectURL(destination
					+ this.createUrlParameters(parameters, "notequalpass")));

			return;
		}

		if (this.wrongCaptcha(parameters))
		{
			response.sendRedirect(response.encodeRedirectURL(destination
					+ this.createUrlParameters(parameters, "isrobot")));

			return;
		}

		try
		{
			this.handleUserCreation(parameters);
			response.sendRedirect(response.encodeRedirectURL("./"));
		}
		catch (AlreadyExistingException e)
		{
			response.sendRedirect(response.encodeRedirectURL(destination
					+ this.createUrlParameters(parameters, "taken")));
		} catch (InvalidDateException e) {
			
			response.sendRedirect("./registration?error="+Errors.dateInFuture);
					
		}

	}

	private boolean wrongCaptcha(Map<String, String> parameters)
	{
		int key = Integer.parseInt(parameters.get("captcha"));
		String value = parameters.get("captchaResult");

		if (value == null)
			return true;

		CaptchaGeneratorRemote captchaValidator = this
				.lookUp(CaptchaGeneratorRemote.class);

		return !captchaValidator.validateCaptcha(key, value);
	}

	private void handleUserCreation(Map<String, String> parameters)
			throws AlreadyExistingException, InvalidDateException
	{

		UserCreationHandlerRemote usercreationBean = this
				.lookUp(UserCreationHandlerRemote.class);
		String userName = parameters.get("username");
		String password = parameters.get("passid");
		String email = parameters.get("email");
		String name = parameters.get("name");
		String sex = parameters.get("sex");
		String surname = parameters.get("surname");
		String bday = parameters.get("bday");
		String city = parameters.get("city");
		String street = parameters.get("street");
		String number = parameters.get("number");

		usercreationBean.createNotConfirmedUser(userName, password, email,
				name, sex.charAt(0), surname, bday, city, street, number,
				WebsiteParameters.site);
	}

	

	private boolean noSamePassword(Map<String, String> parameters)
	{
		String password_confirm = parameters.get("passid_confirm");
		String password = parameters.get("passid");
		return !password.equals(password_confirm);
	}

	private boolean missMandatory(Map<String, String> parameters)
	{
		String email = parameters.get("email");
		String userName = parameters.get("username");
		String password = parameters.get("passid");
		if (email == null || userName == null || password == null)
			return true;
		else if (email.equals("") || userName.equals("") || password.equals(""))
			return true;
		else
			return false;

	}

	private Map<String, String> createCorrectMap(Map<?, ?> parameterMap)
	{
		Map<String, String> correctMap = new HashMap<String, String>();
		for (Entry<?, ?> entry : parameterMap.entrySet())
		{
			String key = (String) entry.getKey();
			String[] valueArray = (String[]) entry.getValue();
			StringBuilder builder = new StringBuilder();
			for (int i = 0; i < valueArray.length; i++)
			{
				builder.append(valueArray[i]);
			}
			correctMap.put(key, builder.toString());
		}
		if (!correctMap.containsKey("sex"))
			correctMap.put("sex", "N");

		return correctMap;
	}

	private String createUrlParameters(Map<String, String> parameters,
			String status)
	{
		StringBuilder builder = new StringBuilder("?");
		for (Entry<String, String> entry : parameters.entrySet())
		{

			builder.append(entry.getKey());
			builder.append('=');
			builder.append(entry.getValue());
			builder.append('&');
		}
		builder.append("status=");
		builder.append(status);

		return builder.toString();
	}
}
